import {create} from 'zustand';
import {chromeStorage} from '@/lib/chromeStorage';
import {STORAGE_KEYS} from '@/lib/storageKeys';

export const makeCollectionPreferenceKey = (spaceId: number, collectionId: number): string => `${spaceId}:${collectionId}`;

interface PersistedPreferences {
  sidebarIsCollapsed?: boolean;
  sidebarWidth?: number;
  expandedCollections?: Record<string, boolean>;
  recentSpaceColors?: string[];
  updatedAt?: number;
}

interface PreferencesState {
  sidebarIsCollapsed: boolean;
  sidebarWidth: number;
  expandedCollections: Record<string, boolean>;
  recentSpaceColors: string[];
  loading: boolean;
  error: string | null;

  loadPreferences: () => Promise<void>;
  setSidebarCollapsed: (collapsed: boolean) => void;
  toggleSidebarCollapsed: () => void;
  setSidebarWidth: (width: number) => void;
  setCollectionExpanded: (spaceId: number, collectionId: number, expanded: boolean) => void;
  removeCollectionExpansionState: (spaceId: number, collectionId: number) => void;
  pruneCollectionExpansionStates: (spaceId: number, collectionIds: number[]) => void;
  setAllCollectionsExpanded: (spaceId: number, collectionIds: number[], expanded: boolean) => void;
  addRecentSpaceColor: (color: string) => void;
  clearRecentSpaceColors: () => void;
}

const MAX_RECENT_COLORS = 10;

const defaultPreferences: PreferencesState = {
  sidebarIsCollapsed: false,
  sidebarWidth: 60,
  expandedCollections: {},
  recentSpaceColors: [],
  loading: false,
  error: null,
  loadPreferences: async () => undefined,
  setSidebarCollapsed: () => undefined,
  toggleSidebarCollapsed: () => undefined,
  setSidebarWidth: () => undefined,
  setCollectionExpanded: () => undefined,
  removeCollectionExpansionState: () => undefined,
  pruneCollectionExpansionStates: () => undefined,
  setAllCollectionsExpanded: () => undefined,
  addRecentSpaceColor: () => undefined,
  clearRecentSpaceColors: () => undefined,
};

const normalizeColor = (color: string): string => color.trim().toLowerCase();

const serializePreferences = (partial: Partial<PreferencesState>): PersistedPreferences => {
  const result: PersistedPreferences = {};
  if (partial.sidebarIsCollapsed !== undefined) {
    result.sidebarIsCollapsed = partial.sidebarIsCollapsed;
  }
  if (partial.sidebarWidth !== undefined) {
    result.sidebarWidth = partial.sidebarWidth;
  }
  if (partial.expandedCollections !== undefined) {
    result.expandedCollections = partial.expandedCollections;
  }
  if (partial.recentSpaceColors !== undefined) {
    result.recentSpaceColors = partial.recentSpaceColors;
  }
  result.updatedAt = Date.now();
  return result;
};

const saveToStorage = async (partial: Partial<PreferencesState>) => {
  try {
    const prev = (await chromeStorage.load<PersistedPreferences>(STORAGE_KEYS.USER_PREFERENCES)) || {};
    const next = {...prev, ...serializePreferences(partial)};
    await chromeStorage.save(STORAGE_KEYS.USER_PREFERENCES, next);
  } catch (error) {
    console.error('保存用户偏好失败:', error);
  }
};

const deserializePreferences = (prefs: PersistedPreferences | null) => {
  if (!prefs) {
    return {
      sidebarIsCollapsed: defaultPreferences.sidebarIsCollapsed,
      sidebarWidth: defaultPreferences.sidebarWidth,
      expandedCollections: {},
      recentSpaceColors: [],
    } as any;
  }

  const expanded = prefs.expandedCollections ? {...prefs.expandedCollections} : {};
  return {
    sidebarIsCollapsed: prefs.sidebarIsCollapsed ?? defaultPreferences.sidebarIsCollapsed,
    sidebarWidth: prefs.sidebarWidth ?? defaultPreferences.sidebarWidth,
    expandedCollections: expanded,
    recentSpaceColors: Array.isArray(prefs.recentSpaceColors)
      ? prefs.recentSpaceColors
          .filter((item) => typeof item === 'string' && /^#([0-9a-fA-F]{3}){1,2}$/.test(item))
          .map(normalizeColor)
          .slice(0, MAX_RECENT_COLORS)
      : [],
  } as any;
};

export const usePreferencesStore = create<PreferencesState>((set, get) => ({
  ...defaultPreferences,

  loadPreferences: async () => {
    set({loading: true, error: null});
    try {
      const prefs = await chromeStorage.load<PersistedPreferences>(STORAGE_KEYS.USER_PREFERENCES);
      const next = deserializePreferences(prefs);
      set({
        sidebarIsCollapsed: next.sidebarIsCollapsed,
        sidebarWidth: next.sidebarWidth,
        expandedCollections: next.expandedCollections,
        recentSpaceColors: next.recentSpaceColors,
        loading: false,
      });
    } catch (error) {
      console.error('加载用户偏好失败:', error);
      set({
        error: error instanceof Error ? error.message : '加载用户偏好失败',
        loading: false,
      });
    }
  },

  setSidebarCollapsed: (collapsed) => {
    set({sidebarIsCollapsed: collapsed});
    void saveToStorage({sidebarIsCollapsed: collapsed, sidebarWidth: get().sidebarWidth});
  },

  toggleSidebarCollapsed: () => {
    const next = !get().sidebarIsCollapsed;
    set({sidebarIsCollapsed: next});
    void saveToStorage({sidebarIsCollapsed: next, sidebarWidth: get().sidebarWidth});
  },

  setSidebarWidth: (width) => {
    set({sidebarWidth: width});
    void saveToStorage({sidebarIsCollapsed: get().sidebarIsCollapsed, sidebarWidth: width});
  },

  setCollectionExpanded: (spaceId, collectionId, expanded) => {
    const key = makeCollectionPreferenceKey(spaceId, collectionId);
    set((state) => ({
      expandedCollections: {...state.expandedCollections, [key]: expanded},
    }));
    void saveToStorage({expandedCollections: {...get().expandedCollections}});
  },

  removeCollectionExpansionState: (spaceId, collectionId) => {
    const key = makeCollectionPreferenceKey(spaceId, collectionId);
    set((state) => {
      if (!(key in state.expandedCollections)) {
        return state;
      }
      const next = {...state.expandedCollections};
      delete next[key];
      return {expandedCollections: next};
    });
    void saveToStorage({expandedCollections: {...get().expandedCollections}});
  },

  pruneCollectionExpansionStates: (spaceId, collectionIds) => {
    const keys = new Set(collectionIds.map((id) => makeCollectionPreferenceKey(spaceId, id)));
    set((state) => {
      const current = state.expandedCollections;
      const next: Record<string, boolean> = {};
      let changed = false;
      for (const [key, value] of Object.entries(current)) {
        if (key.startsWith(`${spaceId}:`) && !keys.has(key)) {
          changed = true;
          continue;
        }
        next[key] = value;
      }
      if (!changed) return state;
      return {expandedCollections: next};
    });
    void saveToStorage({expandedCollections: {...get().expandedCollections}});
  },

  setAllCollectionsExpanded: (spaceId, collectionIds, expanded) => {
    set((state) => {
      const next = {...state.expandedCollections};
      for (const id of collectionIds) {
        const key = makeCollectionPreferenceKey(spaceId, id);
        next[key] = expanded;
      }
      return {expandedCollections: next};
    });
    void saveToStorage({expandedCollections: {...get().expandedCollections}});
  },

  addRecentSpaceColor: (color) => {
    const normalized = normalizeColor(color);
    if (!/^#([0-9a-fA-F]{3}){1,2}$/.test(normalized)) return;
    set((state) => {
      const next = [normalized, ...state.recentSpaceColors.filter((c) => c !== normalized)].slice(0, MAX_RECENT_COLORS);
      return {recentSpaceColors: next};
    });
    void saveToStorage({recentSpaceColors: get().recentSpaceColors});
  },

  clearRecentSpaceColors: () => {
    set({recentSpaceColors: []});
    void saveToStorage({recentSpaceColors: []});
  },
}));

export const selectSidebarIsCollapsed = (state: PreferencesState) => state.sidebarIsCollapsed;
export const selectSidebarWidth = (state: PreferencesState) => state.sidebarWidth;
export const selectExpandedCollections = (state: PreferencesState) => state.expandedCollections;
export const selectRecentSpaceColors = (state: PreferencesState) => state.recentSpaceColors;

(async () => {
  try {
    await usePreferencesStore.getState().loadPreferences();
  } catch (error) {
    console.error('模块初始化时加载用户偏好失败:', error);
  }
})();
